﻿#region License

/*
 © 2012 Alex Kazaev
 * FolderDrive project [http://folderdrive.codeplex.com/]
 * Licensed under Ms-PL license [http://www.opensource.org/licenses/MS-PL]
 */

#endregion License

using System;
using System.Runtime.InteropServices;

namespace FolderDrive.Core
{
  /// <summary>
  /// Allows creation and deletion of drive mappings
  /// </summary>
  public static class FolderDosDevice
  {
    #region dllimports

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool DefineDosDevice(int flags, string devname, string path);

    #endregion dllimports

    #region methods

    /// <summary>
    /// Maps the virtual DOS drive.
    /// </summary>
    /// <param name="drive">The drive letter.</param>
    /// <param name="path">The path.</param>
    /// <returns>true if succeeded, otherwise false</returns>
    public static bool MapDrive(string drive, string path)
    {
      return DefineDosDevice(0, drive, path);
    }

    /// <summary>
    /// Unmaps the drive.
    /// </summary>
    /// <param name="drive">The drive to unmap.</param>
    /// <returns>true if the drive is unmapped, otherwise false</returns>
    public static bool UnmapDrive(string drive)
    {
      return DefineDosDevice((int)DefineDosDeviceFunction.DddRemoveDefinition, drive, null);
    }

    #endregion methods

    #region Nested type: DefineDosDeviceFunction

    [Flags]
    private enum DefineDosDeviceFunction
    {
      /// <summary>
      /// If this value is specified along with DDD_REMOVE_DEFINITION, the function will use
      /// an exact match to determine which mapping to remove. Use this value to ensure that
      /// you do not delete something that you did not define.
      /// </summary>
      DddExactMatchOnRemove = 0x00000004,
      /// <summary>
      /// Do not broadcast the WM_SETTINGCHANGE message. By default, this message is broadcast
      /// to notify the shell and applications of the change.
      /// </summary>
      DddNoBroadcastSystem = 0x00000008,
      /// <summary>
      /// Uses the lpTargetPath string as is. Otherwise, it is converted from an MS-DOS path to a path.
      /// </summary>
      DddRawTargetPath = 0x00000001,
      /// <summary>
      /// Removes the specified definition for the specified device. To determine which definition to
      /// remove, the function walks the list of mappings for the device, looking for a match of
      /// lpTargetPath against a prefix of each mapping associated with this device. The first mapping
      /// that matches is the one removed, and then the function returns.
      ///If lpTargetPath is NULL or a pointer to a NULL string, the function will remove the first
      ///mapping associated with the device and pop the most recent one pushed. If there is nothing
      ///left to pop, the device name will be removed.
      ///If this value is not specified, the string pointed to by the lpTargetPath parameter will
      ///become the new mapping for this device.
      /// </summary>
      DddRemoveDefinition = 0x00000002
    }

    #endregion Nested type: DefineDosDeviceFunction
  }
}